package com.jml.service.order.impl;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collections;

@RestController
@Slf4j
public class SeckillService {

    public SeckillService() {
        initSeckillRule();
    }
    //初始化把限流规则加载到内存中
    private void initSeckillRule() {
        ParamFlowRule rule = new ParamFlowRule(SEKILL_RULE)
                // 对我们接口第0个参数实现限流
                .setParamIdx(0)//限流类型是QPS
                .setGrade(RuleConstant.FLOW_GRADE_QPS)
                // 每秒QPS最多只有1s
                .setCount(1);
        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
        log.info(">>>秒杀接口限流策略配置成功<<<");
    }

    /**
     * 秒杀路由资源
     */
    private static final String SEKILL_RULE = "seckill";


    /**
     * 秒杀抢购
     */
    @RequestMapping("/seckill")
    public String seckill(Long userId, Long orderId) {
        try {
            //把限流接口和规则匹配上，对userId这个参数限流，每秒访问一次。
            Entry entry = SphU.entry(SEKILL_RULE, EntryType.IN, 1, userId);
            return userId+"秒杀成功";
        } catch (Exception e) {
            return "当前用户访问过度频繁，请稍后重试!";
        }
    }


    /**
     * 热词限流控制台配置
     */
    private static final String seckillcon = "seckillcon";
    @RequestMapping("/seckillCon")
    @SentinelResource(value = seckillcon)
    public String seckillCon(Long userId, Long orderId) {
        Long i = 10/userId;
        return "秒杀成功";
    }
}
